package rails;

import java.util.ArrayList;

import semaphores.Semaphore;
import train.Train;

/**
 * This class is used to simulate rails on a train network.
 * It has a length, known as the attribute longueur, in a number of sections. 
 * The attributes jonction1 and jonction2 allow us to know the two junctions at each end of the rail.
 * 
 * @author BERNARD Arthur, DELAMARCHE J�r�me, LE STER Olivier, PAVAGEAU Max
 *
 */

public class Rail {
	
	/**
	 * The length, in sections, of the rail.
	 */
	private int longueur;
	
	/**
	 * The junction at one of the two ends of the rail.
	 * 
	 * @see Jonction
	 */
	private Jonction jonction1;
	
	/**
	 * The junction at the other end of the rail.
	 * 
	 * @see Jonction
	 */
	private Jonction jonction2;
	
	/**
	 * The semaphore at one of the two ends of the rail.
	 * 
	 * @see Semaphore
	 */
	private Semaphore semaphore1;
	
	/**
	 * The semaphore at the other end of the rail.
	 * 
	 * @see Semaphore
	 */
	private Semaphore semaphore2;
	
	private ArrayList<Train> trains;
	
	/**
	 * Basic constructor.
	 */
	public Rail() {
		longueur = 0;
		jonction1 = null;
		jonction2 = null;
		semaphore1 = null;
		semaphore2 = null;
		trains = new ArrayList<Train>();
	}
	
	/**
	 * Constructor with a length for the rail.
	 * 
	 * @param longueur The length of the rail as a number of sections
	 */
	public Rail(int longueur) {
		this.longueur = longueur;
		jonction1 = null;
		jonction2 = null;
		semaphore1 = null;
		semaphore2 = null;
		trains = new ArrayList<Train>();
	}
	
	/**
	 * Constructor with a length for the rail and the two junctions.
	 * 
	 * @param longueur The length of the rail as a number of sections
	 * @param jonction1
	 * @param jonction2
	 */
	public Rail(int longueur, Jonction jonction1, Jonction jonction2) {
		this.longueur = longueur;
		this.jonction1 = jonction1;
		this.jonction2 = jonction2;
		semaphore1 = null;
		semaphore2 = null;
		trains = new ArrayList<Train>();
	}
	
	/**
	 * Constructor with a length for the rail, the two junctions and the two semaphores
	 * 
	 * @param longueur The length of the rail as a number of sections
	 * @param jonction1
	 * @param jonction2
	 * @param semaphore1
	 * @param semaphore2
	 */
	public Rail(int longueur, Jonction jonction1, Jonction jonction2, Semaphore semaphore1, Semaphore semaphore2) {
		this.longueur = longueur;
		this.jonction1 = jonction1;
		this.jonction2 = jonction2;
		this.semaphore1 = semaphore1;
		this.semaphore2 = semaphore2;
		trains = new ArrayList<Train>();
	}
	
	/**
	 * Returns the length of the rail.
	 * 
	 * @return The number of sections constituting the rail.
	 */
	public int getLongueur() {
		return longueur;
	}

	/**
	 * Sets the length of the rail.
	 * 
	 * @param longueur The number of sections.
	 */
	public void setLongueur(int longueur) {
		this.longueur = longueur;
	}

	/**
	 * Returns the desired junction of this rail
	 * 
	 * @param i The number of the junction.
	 * @return The first junction.
	 */
	public Jonction getjonction(int i) {
		if(i == 1) 
			return jonction1;
		
		return jonction2;
	}
	
	public void setjonction(Jonction jonction, int i) {
		if(i == 1) 
			jonction1 = jonction;
		else
			jonction2 = jonction;
	}
	
	/**
	 * Returns the desired semaphore of this rail
	 * 
	 * @param i The number of the semaphore.
	 * @return The first semaphore.
	 */
	public Semaphore getSemaphore(int i) {
		if(i == 1) 
			return semaphore1;
		
		return semaphore2;
	}

	/**
	 * Sets the i semaphore of the rail.
	 * 
	 * @param semaphore The first junction of the rail
	 * @param i The number of the semaphore
	 */
	public void setSemaphore(Semaphore semaphore, int i) {
		if(i == 1)
			this.semaphore1 = semaphore;
		
		this.semaphore2 = semaphore;
	}
	
	/**
	 * Adds a train on the rail.
	 * 
	 * @param train The train to add.
	 */
	public void ajoutTrain(Train train) {
		trains.add(train);
	}
	
	/**
	 * Removes a train from the rail.
	 * 
	 * @param train The train to remove.
	 */
	public void enleverTrain(Train train) {
		trains.remove(train);
	}
	
	/**
	 * Returns the list of trains on the rail.
	 * 
	 * @return The list of trains.
	 */
	public ArrayList<Train> getTrains() {
		return trains;
	}
	
	public String toString() {
		return this.hashCode() + " (" + getLongueur() + ")";
	}
}
